home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 / Ham Radio 2000.iso / ham2000 / tcp_ip / os2 / pmnos11s / rarp.c < prev    next >
Text File  |  1993-07-30  |  6KB  |  218 lines

  1. /* Reverse Address Resolution Protocol (ARP) functions. Sits between IP and
  2.  * Level 2, mapping Level 2 addresses to IP.
  3.  */
  4. #include "global.h"
  5. #include "mbuf.h"
  6. #include "proc.h"
  7. #include "timer.h"
  8. #include "iface.h"
  9. #include "socket.h"
  10. #include "ax25.h"
  11. #include "arp.h"
  12. #include "netuser.h"
  13. #include "cmdparse.h"
  14. #include "pktdrvr.h"
  15.  
  16. struct arp_stat Rarp_stat;
  17. static int Rwaiting = 0;    /* Semaphore used when waiting for a reply */
  18. static void arp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target));
  19. static int dorarpquery __ARGS((int argc,char *argv[],void *p));
  20. static void rarpstat __ARGS((void));
  21. static void rarp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target));
  22.  
  23. static struct cmds Rarpcmds[] = {
  24.     "query", dorarpquery, 0, 3,
  25. #ifdef fixed
  26.     "rarp query <interface> <ether addr|callsign> [<ether addr|callsign>]",
  27. #else
  28.     "rarp query <interface> <callsign> [<ether addr|callsign>]",
  29. #endif
  30.     NULLCHAR
  31. };
  32.  
  33. int
  34. dorarp(argc,argv,p)
  35. int argc;
  36. char *argv[];
  37. void *p;
  38. {
  39.     if(argc < 2){
  40.         rarpstat();
  41.         return 0;
  42.     }
  43.     return subcmd(Rarpcmds,argc,argv,p);
  44. }
  45.  
  46. static int
  47. dorarpquery(argc,argv,p)
  48. int argc;
  49. char *argv[];
  50. void *p;
  51. {
  52.     struct iface *ifp;
  53.     char hwaddr[MAXHWALEN], qhwaddr[MAXHWALEN];
  54.     int16 hardware, t;
  55.     static char *errmsg = "Illegal hardware address\n";
  56.     if((ifp = if_lookup(argv[1])) == NULLIF){
  57.          tprintf(Badinterface,argv[1]);
  58.          return -1;
  59.     }
  60.     switch(ifp->iftype->type) {
  61.     case CL_AX25:
  62.          hardware = ARP_AX25;
  63.          break;
  64. #ifdef fixed
  65.     case CL_ETHERNET:
  66.          hardware = ARP_ETHER;
  67.          break;
  68.     default:
  69.          tputs("Only Ethernet and AX25 interfaces allowed\n");
  70. #else
  71.     default:
  72.          tputs("Only AX25 interfaces allowed\n");
  73. #endif
  74.          return -1;
  75.     }
  76.     if((*ifp->iftype->scan)(hwaddr,argv[2]) == -1) {
  77.          tputs(errmsg);
  78.          return -1;
  79.     }
  80.     if(argc > 3 && (*ifp->iftype->scan)(qhwaddr,argv[3]) == -1) {
  81.          tputs(errmsg);
  82.          return -1;
  83.     }
  84.     if(argc == 3)
  85.          memcpy(qhwaddr,hwaddr,ifp->iftype->hwalen);
  86.     rarp_output(ifp,hardware,hwaddr,qhwaddr);
  87.  
  88.     t = Arp_type[hardware].pendtime;
  89.     ++Rwaiting;
  90.     tprintf("Trying...   %2d",t);
  91.     while(t--) {
  92.          alarm(1000L);
  93.          if(pwait(&Rwaiting) != EALARM) {
  94.           alarm(0);
  95.           --Rwaiting;
  96.           return 0;
  97.          }
  98.          tprintf("\b\b%2d",t);
  99.     }
  100.     tputs("\b\bTimeout.\n");
  101.     --Rwaiting;
  102.     return 0;
  103. }
  104.  
  105. /* Handle incoming RARP packets according to RFC 903.
  106.  */
  107. void
  108. rarp_input(iface,bp)
  109. struct iface *iface;
  110. struct mbuf *bp;
  111. {
  112.     struct arp rarp;
  113.     struct arp_type *at;
  114.     char shwaddr[MAXHWALEN];
  115.     
  116.     Rarp_stat.recv++;
  117.     if(ntoharp(&rarp,&bp) == -1)    /* Convert into host format */
  118.         return;
  119.     if(rarp.hardware >= NHWTYPES){
  120.         /* Unknown hardware type, ignore */
  121.         Rarp_stat.badtype++;
  122.         return;
  123.     }
  124.     at = &Arp_type[rarp.hardware];
  125.     if(rarp.protocol != at->iptype){
  126.         /* Unsupported protocol type, ignore */
  127.         Rarp_stat.badtype++;
  128.         return;
  129.     }
  130.     if(uchar(rarp.hwalen) > MAXHWALEN || uchar(rarp.pralen) != sizeof(int32)){
  131.         /* Incorrect protocol addr length (different hw addr lengths
  132.          * are OK since AX.25 addresses can be of variable length)
  133.          */
  134.         Rarp_stat.badlen++;
  135.         return;
  136.     }
  137.     if(memcmp(rarp.shwaddr,at->bdcst,at->hwalen) == 0){
  138.         /* This guy is trying to say he's got the broadcast address! */
  139.         Rarp_stat.badaddr++;
  140.         return;
  141.     }
  142.     if(rarp.opcode == REVARP_REQUEST) {
  143.         /* We are not a server, so we can only answer requests for a
  144.          * hardware address that is our own. But would be possible to
  145.          * use the ARP table to answer requests for someone elses
  146.          * IP address.
  147.          */
  148.         if(memcmp(rarp.thwaddr,iface->hwaddr,at->hwalen) == 0) {
  149.             memcpy(shwaddr,rarp.shwaddr,at->hwalen);
  150.             /* Mark the end of the sender's AX.25 address
  151.              * in case he didn't
  152.              */
  153.             if(rarp.hardware == ARP_AX25)
  154.                 rarp.thwaddr[uchar(rarp.hwalen)-1] |= E;
  155.             memcpy(rarp.shwaddr,iface->hwaddr,at->hwalen);
  156.             rarp.sprotaddr = iface->addr;
  157.             rarp.tprotaddr = iface->addr;
  158.             rarp.opcode = REVARP_REPLY;
  159.  
  160.             if((bp = htonarp(&rarp)) == NULLBUF)
  161.                 return;
  162.  
  163.             if(iface->forw != NULLIF)
  164.                  (*iface->forw->output)(iface->forw,shwaddr,
  165.                     iface->forw->hwaddr,at->rarptype,bp);
  166.             else
  167.                  (*iface->output)(iface,shwaddr,
  168.                     iface->hwaddr,at->rarptype,bp);
  169.             Rarp_stat.inreq++;
  170.         }
  171.     } else {
  172.         Rarp_stat.replies++;
  173.         if(Rwaiting) {
  174.              psignal(&Rwaiting,1);
  175.              tprintf("\nRARP Reply: %s %s\n",
  176.                  (*at->format)(shwaddr,rarp.thwaddr),
  177.                  inet_ntoa(rarp.tprotaddr));
  178.         }
  179.     }
  180. }
  181.  
  182. /* Send a RARP request to target to resolve hardware address hwaddr */
  183. static void
  184. rarp_output(struct iface *iface,int16 hardware, char *hwaddr,char *target)
  185. {
  186.     struct arp rarp;
  187.     struct mbuf *bp;
  188.     struct arp_type *at;
  189.  
  190.     at = &Arp_type[hardware];
  191. //    if(iface->output == NULLFP)
  192.     if(iface->output == 0)
  193.         return;
  194.     
  195.     rarp.hardware = hardware;
  196.     rarp.protocol = at->iptype;
  197.     rarp.hwalen = at->hwalen;
  198.     rarp.pralen = sizeof(int32);
  199.     rarp.opcode = REVARP_REQUEST;
  200.     memcpy(rarp.shwaddr,iface->hwaddr,at->hwalen);
  201.     rarp.sprotaddr = 0;
  202.     memcpy(rarp.thwaddr,hwaddr,at->hwalen);
  203.     rarp.tprotaddr = 0;
  204.     if((bp = htonarp(&rarp)) == NULLBUF)
  205.         return;
  206.     (*iface->output)(iface,target,
  207.         iface->hwaddr,at->rarptype,bp);
  208.     Rarp_stat.outreq++;
  209. }
  210.  
  211. static void
  212. rarpstat()
  213. {
  214.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  215.      Rarp_stat.recv,Rarp_stat.badtype,Rarp_stat.badaddr,Rarp_stat.inreq,
  216.      Rarp_stat.replies,Rarp_stat.outreq);
  217. }
  218.